﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DTOFrameworks;
using System.Xml;
using System.Data;
using System.Collections;
using FooFun.DataElements.Dtos;
using FooFun.Faq.Dal;
using System.Data.Common;

namespace PhysicalDataProvider
{
    public class TopicService : ITopicService, IReplyService
    {
        DEDataProvider dataProvider;

        public DEDataProvider DataProvider
        {
            get { return dataProvider; }
            set { dataProvider = value; }
        }

        string[] insertCols = new string[]
        {
           "TopicId","Content"
        };

        string[] selectCols = new string[] { "Content" };
        // todo: 针对专门列的更新操作
        string[] updateCols = new string[] { "Content" };

        string table = "t_Topics";

        string idCol = "TopicId";

        public IDataElement GetElement(Guid guid)
        {
            string sql = @"SELECT t_TopicIndex.TopicId,Content 
FROM t_TopicIndex, t_Topics
WHERE t_TopicIndex.TopicId = t_Topics.TopicId AND t_TopicIndex.TopicId = '{0}'";

            sql = string.Format(sql,
                DataProviderUtil.GetGuidBase64(guid));

            IDataElement dbDE = DataProvider.GetScalar(
                sql, selectCols, "t_TopicIndex");

            foreach (IDataElement item in dbDE)
            {
                TopicDataElement objDE = new TopicDataElement(item);

                return objDE;
            }

            return new EmptyDataElement("没有找到问题");
        }

        public IDataElement GetElement(IDataElement de)
        {
            string sql = @"SELECT t_TopicIndex.TopicId,Content 
FROM t_TopicIndex, t_Topics
WHERE t_TopicIndex.TopicId = t_Topics.TopicId AND t_TopicIndex.TopicId='{0}'";

            sql = string.Format(sql,
                DataProviderUtil.GetGuidBase64(de.Value));

            IDataElement dbDE = DataProvider.GetScalar(
                sql, selectCols, "t_TopicIndex");

            foreach (IDataElement item in dbDE)
            {
                TopicDataElement objDE = new TopicDataElement(item);

                return objDE;
            }

            return new EmptyDataElement("没有找到问题");
        }

        public void UpdateTopic(IDataElement objDE)
        {
            IDataElement xmlDE = null;
            if (objDE is XmlElementDataElement)
            {
                xmlDE = objDE;
            }
            else if (objDE is CustomDataElement)
            {
                xmlDE = ((CustomDataElement)objDE).InnerDataElement;
            }
            TopicDbDataElement dbDE = new TopicDbDataElement(xmlDE);
            DataProvider.Update(dbDE, idCol, updateCols, table);
        }

        private void AddReply(IDataElement objDE, string reply, Guid eventId, Guid accounId)
        {
            // todo： 用工厂实现
            ContentService contentManager = new ContentService();

            IDataElement de = objDE["Replys"];

            IDataElement contentDE = contentManager.CreateContent
                (de, reply);

            contentDE["@EventId"].Value
                = DataProviderUtil.GetGuid32(eventId);

            de.Add(contentDE);

            objDE["@Status"].Value = TopicStatus.Relyed;

            this.UpdateTopic(objDE);
        }

        public void AddRemark(IDataElement objDE, string remark, Guid eventId)
        {
            ContentService contentManager = new ContentService();

            IDataElement de = objDE["Remarks"];

            IDataElement contentDE = contentManager.CreateContent
                (de, remark);

            contentDE["@EventId"].Value =
                DataProviderUtil.GetGuid32(eventId);

            de.Add(contentDE);

            this.UpdateTopic(objDE);
        }

        private void AddConclusion
            (IDataElement objDE, Guid eventId, Guid replyId, string conclusion)
        {
            ContentService contentService = new ContentService();

            IDataElement de = objDE["Conclusion"];

            IDataElement contentDE = contentService.CreateContent
                (de, conclusion);

            contentDE["@EventId"].Value
                = DataProviderUtil.GetGuid32(eventId);

            contentDE["@Ref"].Value = DataProviderUtil.GetGuid32(replyId);

            de.Add(contentDE);

            objDE["@Status"].Value = TopicStatus.Sealed;

            objDE["Replys"]["@Top"].Value = DataProviderUtil.GetGuid32(replyId);

            this.UpdateTopic(objDE);
        }

        #region ITopicService 成员

        public void CreateTopic(string topicTitle, string remark, Guid eventId, Guid forumId, Guid userId)
        {
            XmlDocument doc = new XmlDocument();

            XmlElement topicEle = doc.CreateElement("Topic");
            doc.AppendChild(topicEle);

            XmlElement titleEle = doc.CreateElement("Title");
            topicEle.AppendChild(titleEle);

            XmlElement contentEle = doc.CreateElement("Content");
            contentEle.InnerText = topicTitle;
            titleEle.AppendChild(contentEle);

            XmlElementDataElement de
                = new XmlElementDataElement(topicEle);

            de["@ForumId"].Value = DataProviderUtil.GetGuid32(forumId);
            de["@EventId"].Value = DataProviderUtil.GetGuid32(eventId);
            de["@Status"].Value = TopicStatus.Asked;
            de["@TopicId"].Value = DataProviderUtil.GetGuid32(eventId);

            de["Title"]["Content"]["@EventId"].Value
                = DataProviderUtil.GetGuid32(eventId);

            if (!string.IsNullOrEmpty(remark))
            {
                IDataElement contentDE = de["Remarks"]["Content"];
                contentDE["@EventId"].Value
                    = DataProviderUtil.GetGuid32(eventId);

                contentDE.Value = remark;
            }

            TopicDbDataElement dbDE = new TopicDbDataElement(de);

            DataProvider.Insert(dbDE, insertCols, table);
        }

        public void MoveTopic(IDataElement topic, Guid forumId)
        {
            topic["@ForumId"].Value
                = DataProviderUtil.GetGuidBase64(forumId);

            this.UpdateTopic(topic);
        }

        public void RemoveTopic(Guid topicId)
        {
            return;
        }

        #endregion

        #region IReplyService 成员

        public void AddReply(IDataElement topic, Guid eventId, Guid userId, string reply)
        {
            this.AddReply(topic, reply, eventId, userId);
        }

        public void Conclude(IDataElement topic, Guid eventId, Guid replyId, string conclusion)
        {
            AddConclusion(topic, eventId, replyId, conclusion);
        }

        #endregion

        public int CountRelpyForUser(Guid userId)
        {
            using (DbConnection conn = SqlHelper.Connection)
            {
                DbCommand cmd = conn.CreateCommand();

                string sql = @"
SElECT Count(*) FROM t_ReplyIndex WHERE TopicId IN
(SELECT TopicId FROM t_TopicIndex WHERE UserId=?)";

                cmd.CommandText = sql;

                DbParameter para = cmd.CreateParameter();
                para.Value = DataProviderUtil.GetGuidBase64(userId);

                cmd.Parameters.Add(para);

                conn.Open();

                int count = Convert.ToInt32(cmd.ExecuteScalar());

                conn.Close();

                return count;
            }
        }

        public int CountTopReplyForUser(Guid userId)
        {
            using (DbConnection conn = SqlHelper.Connection)
            {
                DbCommand cmd = conn.CreateCommand();

                string sql = @"
SElECT Count(*) FROM t_TopicIndex WHERE UserId=? AND Status=?";

                cmd.CommandText = sql;

                DbParameter para = cmd.CreateParameter();
                para.Value = DataProviderUtil.GetGuidBase64(userId);
                cmd.Parameters.Add(para);

                para = cmd.CreateParameter();
                para.Value = (int)TopicStatus.Sealed;
                cmd.Parameters.Add(para);

                conn.Open();

                int count = Convert.ToInt32(cmd.ExecuteScalar());

                conn.Close();

                return count;
            }
        }
    }
}
